#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
参数处理器模块

该模块提供参数处理和班次生成策略，用于处理三班制排班接口的参数。
"""

import logging
from datetime import datetime

# 配置日志
logger = logging.getLogger(__name__)


class ParameterProcessor:
    """参数处理器，负责处理和转换传入的参数"""

    def __init__(self, global_params):
        """初始化参数处理器

        Args:
            global_params: 全局配置参数
        """
        self.global_params = global_params

    def process_parameters(self, params):
        """处理传入的参数

        Args:
            params: 传入的参数字典

        Returns:
            processed_params: 处理后的参数字典
        """
        # 创建参数副本，避免修改原参数
        processed_params = params.copy()

        # 如果没有传入任何特殊参数，直接返回原参数
        if not self._has_special_params(processed_params):
            logger.info("未检测到特殊参数，使用原始参数")
            return processed_params

        logger.info(f"检测到特殊参数，开始处理: {self._get_special_params(processed_params)}")

        # 处理班制模式参数
        self._process_shift_mode(processed_params)

        # 处理班次时间范围参数
        self._process_shift_time_range(processed_params)

        # 处理时间间隔参数
        self._process_time_interval(processed_params)

        logger.info(f"参数处理完成: {processed_params}")
        return processed_params

    def _has_special_params(self, params):
        """检查是否传入了特殊参数"""
        special_params = ['day_segments', 'first_segment_start', 'first_segment_end', 'time_interval_minutes']
        # 检查是否传入了特殊参数，并且参数值不为None
        return any(param in params and params[param] is not None for param in special_params)

    def _get_special_params(self, params):
        """获取传入的特殊参数"""
        special_params = ['day_segments', 'first_segment_start', 'first_segment_end', 'time_interval_minutes']
        # 获取传入的特殊参数，并且参数值不为None
        return {param: params[param] for param in special_params if param in params and params[param] is not None}

    def _process_shift_mode(self, params):
        """处理班制模式参数"""
        # 如果传入了day_segments参数
        if 'day_segments' in params:
            day_segments = params['day_segments']

            # 检查是否为None
            if day_segments is None:
                logger.info(f"参数day_segments为None，使用全局参数")
                day_segments = self.global_params.get('day_segments', 3)
                params['day_segments'] = day_segments

            # 验证day_segments参数
            if not isinstance(day_segments, int) or day_segments < 1 or day_segments > 3:
                logger.warning(f"无效的day_segments参数: {day_segments}，使用默认值: 3")
                day_segments = 3
                params['day_segments'] = day_segments

            # 根据day_segments设置shift_mode
            if day_segments == 1:
                params['shift_mode'] = 'one_shift'
                # 设置启用的班次
                params['enabled_shifts'] = ['morning_shift']
                logger.info(f"设置班制模式为一班制: {params['shift_mode']}")
            elif day_segments == 2:
                params['shift_mode'] = 'two_shift'
                # 设置启用的班次
                params['enabled_shifts'] = ['morning_shift', 'night_shift']
                logger.info(f"设置班制模式为二班制: {params['shift_mode']}")
            elif day_segments == 3:
                params['shift_mode'] = 'three_shift'
                # 设置启用的班次
                params['enabled_shifts'] = ['morning_shift', 'afternoon_shift', 'night_shift']
                logger.info(f"设置班制模式为三班制: {params['shift_mode']}")

            # 设置参数优先级标志
            params['param_priority_enabled'] = True

    def _process_shift_time_range(self, params):
        """处理班次时间范围参数"""
        # 如果传入了first_segment_start和first_segment_end参数
        if 'first_segment_start' in params and 'first_segment_end' in params:
            first_start = params['first_segment_start']
            first_end = params['first_segment_end']

            # 检查是否为None
            if first_start is None or first_end is None:
                logger.info(f"参数first_segment_start或first_segment_end为None，不处理班次时间范围")
                return

            # 验证时间格式
            try:
                datetime.strptime(first_start, "%H:%M")
                datetime.strptime(first_end, "%H:%M")
            except ValueError:
                logger.warning(f"无效的时间格式: {first_start} 或 {first_end}，使用默认值")
                first_start = self.global_params.get('shift_start_time', '09:00')
                first_end = self._calculate_shift_end_time(first_start, 8)  # 默认8小时班次
                params['first_segment_start'] = first_start
                params['first_segment_end'] = first_end

            # 创建自定义班次配置
            custom_shifts = {}

            # 根据day_segments设置班次时间范围
            day_segments = params.get('day_segments', self.global_params.get('day_segments', 3))

            if day_segments == 1:
                # 一班制：只有morning_shift
                custom_shifts['morning_shift'] = {
                    'start_time': first_start,
                    'end_time': first_end,
                    'name': '班次1',
                    'order': 1
                }
                logger.info(f"设置一班制时间范围: {first_start}-{first_end}")
            elif day_segments == 2:
                # 二班制：morning_shift和night_shift
                # 计算第二个班次的时间范围
                second_start = first_end
                second_end = first_start

                custom_shifts['morning_shift'] = {
                    'start_time': first_start,
                    'end_time': first_end,
                    'name': '班次1',
                    'order': 1
                }
                custom_shifts['night_shift'] = {
                    'start_time': second_start,
                    'end_time': second_end,
                    'name': '班次2',
                    'order': 2
                }
                logger.info(f"设置二班制时间范围: 班次1={first_start}-{first_end}, 班次2={second_start}-{second_end}")
            elif day_segments == 3:
                # 三班制：morning_shift、afternoon_shift和night_shift
                # 计算每个班次的时间范围
                first_start_hours, first_start_minutes = map(int, first_start.split(':'))
                first_end_hours, first_end_minutes = map(int, first_end.split(':'))

                # 计算第一个班次的时长（小时）
                first_duration = (first_end_hours - first_start_hours) % 24
                if first_duration <= 0:
                    first_duration += 24
                # 考虑分钟差异
                first_duration += (first_end_minutes - first_start_minutes) / 60

                # 计算第二个班次的时间范围
                second_start = first_end
                second_end_hours = int((first_end_hours + first_duration) % 24)
                second_end = f"{second_end_hours:02d}:{first_end_minutes:02d}"

                # 计算第三个班次的时间范围
                third_start = second_end
                third_end = first_start

                custom_shifts['morning_shift'] = {
                    'start_time': first_start,
                    'end_time': first_end,
                    'name': '班次1',
                    'order': 1
                }
                custom_shifts['afternoon_shift'] = {
                    'start_time': second_start,
                    'end_time': second_end,
                    'name': '班次2',
                    'order': 2
                }
                custom_shifts['night_shift'] = {
                    'start_time': third_start,
                    'end_time': third_end,
                    'name': '班次3',
                    'order': 3
                }
                logger.info(f"设置三班制时间范围: 班次1={first_start}-{first_end}, 班次2={second_start}-{second_end}, 班次3={third_start}-{third_end}")

            # 设置自定义班次配置
            params['custom_shifts'] = custom_shifts
            # 设置使用自定义班次配置标志
            params['use_custom_shifts'] = True

    def _process_time_interval(self, params):
        """处理时间间隔参数"""
        # 如果传入了time_interval_minutes参数
        if 'time_interval_minutes' in params:
            time_interval = params['time_interval_minutes']

            # 检查是否为None
            if time_interval is None:
                logger.info(f"参数time_interval_minutes为None，使用全局参数")
                time_interval = self.global_params.get('time_interval_minutes', 20)
                params['time_interval_minutes'] = time_interval

            # 验证time_interval_minutes参数
            if not isinstance(time_interval, int) or time_interval < 10 or time_interval > 60:
                logger.warning(f"无效的time_interval_minutes参数: {time_interval}，使用默认值: 20")
                time_interval = self.global_params.get('time_interval_minutes', 20)
                params['time_interval_minutes'] = time_interval

            # 计算time_slots_per_day
            time_slots_per_day = 24 * 60 // time_interval
            params['time_slots_per_day'] = time_slots_per_day
            logger.info(f"设置时间间隔为{time_interval}分钟，一天{time_slots_per_day}个时间段")

    def _calculate_shift_end_time(self, start_time, duration_hours):
        """计算班次结束时间

        Args:
            start_time: 开始时间，格式为'HH:MM'
            duration_hours: 持续时间（小时）

        Returns:
            end_time: 结束时间，格式为'HH:MM'
        """
        start_hours, start_minutes = map(int, start_time.split(':'))
        end_hours = (start_hours + duration_hours) % 24
        return f"{end_hours:02d}:{start_minutes:02d}"


class ShiftGenerationStrategy:
    """班次生成策略，负责根据参数生成班次"""

    @staticmethod
    def generate_shifts(params, global_params):
        """根据参数生成班次

        Args:
            params: 处理后的参数字典
            global_params: 全局配置参数

        Returns:
            shifts: 生成的班次列表
        """
        # 如果使用自定义班次配置
        if params.get('use_custom_shifts', False):
            return ShiftGenerationStrategy._generate_custom_shifts(params)
        else:
            return ShiftGenerationStrategy._generate_default_shifts(params, global_params)

    @staticmethod
    def _generate_custom_shifts(params):
        """生成自定义班次"""
        custom_shifts = params.get('custom_shifts', {})
        enabled_shifts = params.get('enabled_shifts', [])

        # 根据enabled_shifts筛选班次
        shifts = []
        for shift_type in enabled_shifts:
            if shift_type in custom_shifts:
                shifts.append({
                    'type': shift_type,
                    'start_time': custom_shifts[shift_type]['start_time'],
                    'end_time': custom_shifts[shift_type]['end_time'],
                    'name': custom_shifts[shift_type]['name'],
                    'order': custom_shifts[shift_type]['order']
                })

        logger.info(f"生成自定义班次: {shifts}")
        return shifts

    @staticmethod
    def _generate_default_shifts(params, global_params):
        """生成默认班次"""
        shift_mode = params.get('shift_mode', global_params.get('shift_mode', 'three_shift'))
        shift_start_time = params.get('shift_start_time', global_params.get('shift_start_time', '09:00'))

        # 根据shift_mode生成班次
        if shift_mode == 'one_shift':
            return ShiftGenerationStrategy._generate_one_shift(shift_start_time)
        elif shift_mode == 'two_shift':
            return ShiftGenerationStrategy._generate_two_shift(shift_start_time)
        else:  # three_shift
            return ShiftGenerationStrategy._generate_three_shift(shift_start_time)

    @staticmethod
    def _generate_one_shift(shift_start_time):
        """生成一班制班次"""
        # 一班制：24小时一个班次
        shifts = [{
            'type': 'morning_shift',
            'start_time': shift_start_time,
            'end_time': shift_start_time,  # 24小时后回到起点
            'name': '班次1',
            'order': 1
        }]
        logger.info(f"生成一班制班次: {shifts}")
        return shifts

    @staticmethod
    def _generate_two_shift(shift_start_time):
        """生成二班制班次"""
        # 二班制：每个班次12小时
        start_hours, start_minutes = map(int, shift_start_time.split(':'))

        # 计算第二个班次的开始时间
        second_start_hours = (start_hours + 12) % 24
        second_start = f"{second_start_hours:02d}:{start_minutes:02d}"

        shifts = [
            {
                'type': 'morning_shift',
                'start_time': shift_start_time,
                'end_time': second_start,
                'name': '班次1',
                'order': 1
            },
            {
                'type': 'night_shift',
                'start_time': second_start,
                'end_time': shift_start_time,
                'name': '班次2',
                'order': 2
            }
        ]
        logger.info(f"生成二班制班次: {shifts}")
        return shifts

    @staticmethod
    def _generate_three_shift(shift_start_time):
        """生成三班制班次"""
        # 三班制：每个班次8小时
        start_hours, start_minutes = map(int, shift_start_time.split(':'))

        # 计算第二个班次的开始时间
        second_start_hours = (start_hours + 8) % 24
        second_start = f"{second_start_hours:02d}:{start_minutes:02d}"

        # 计算第三个班次的开始时间
        third_start_hours = (second_start_hours + 8) % 24
        third_start = f"{third_start_hours:02d}:{start_minutes:02d}"

        shifts = [
            {
                'type': 'morning_shift',
                'start_time': shift_start_time,
                'end_time': second_start,
                'name': '班次1',
                'order': 1
            },
            {
                'type': 'afternoon_shift',
                'start_time': second_start,
                'end_time': third_start,
                'name': '班次2',
                'order': 2
            },
            {
                'type': 'night_shift',
                'start_time': third_start,
                'end_time': shift_start_time,
                'name': '班次3',
                'order': 3
            }
        ]
        logger.info(f"生成三班制班次: {shifts}")
        return shifts
